
package com.smartalarmclock.UI;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

//import android.support.v4.app.*;

import com.smartalarmclock.Logic.AcManager;
import com.smartalarmclock.Model.IContact;
import com.smartalarmclock.Model.IProfile;
import com.smartalarmclock.Model.Exceptions.DataEntityDoesNotExistException;
import com.smartalarmclock.Model.Exceptions.PhoneContactDoesNotExistException;

public class CreateNewProfileActivity extends FragmentActivity implements IContactSelector {
	private static final String TAG = "CreateNewProfileActivity";
	private boolean m_IsNew = true;
	private HashMap<IContact, Boolean> m_Contacts;
	private IProfile m_Profile = null;
	
	/** Called when the activity is first created. */
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.create_new_profile_screen);	
	    final Button buttonDelete = (Button)findViewById(R.id.button_delete_profile);
	    Button buttonSave = (Button)findViewById(R.id.button_create_new_profile);
	    final EditText editTextProfileName = (EditText)findViewById(R.id.editText_profile_name);
	    
	    final Button contactButton = (Button)findViewById(R.id.add_contacts);
	    final Button buttonScedule = (Button)findViewById(R.id.sceduele_profile);
	    
	    // read extra messages sent to this activity intent
	    Bundle bundle = this.getIntent().getExtras();

	    m_IsNew = bundle.getBoolean(Messages.PROFILE_DETAILS_IS_NEW);
	    if (!m_IsNew)
	    {
	    	int profileId = bundle.getInt(Messages.PROFILE_DETAILS_PROFILE_ID);
	    	// get profile name
	    	m_Profile = AcManager.GetInstance().GetProfileDetails(this, profileId);
	    	if (m_Profile == null)
	    	{
	    		try {
					throw new DataEntityDoesNotExistException(IProfile.class);
				} catch (DataEntityDoesNotExistException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					Log.v("IProfile", "Existing profile in screen wasn't found in DB");
				}
	    	}
	    	buttonSave.setText("Update");
		    buttonDelete.setOnClickListener(new OnClickDeleteListener(this));
	    }
	    else
	    {
	    	buttonSave.setText("Create");
	    	buttonDelete.setVisibility(View.GONE);
	    }
	    
	    if (m_Profile != null)
	    {
	    	// set profile name in edit text
	    	editTextProfileName.setText(m_Profile.GetName());
	    }
	    	    
	    m_Contacts = new HashMap<IContact, Boolean>();
	    for (IContact contact : GetCurrentlySelectedContacts()) {
	    	m_Contacts.put(contact, true);
	    }
	    
	    // set listeners
	    editTextProfileName.addTextChangedListener(editTextProfileNameChangedListener);
	    buttonSave.setOnClickListener(buttonSaveOnClickListener);
	    	    
        // set profile list adapter and items on-click listener
        final ListView contactListView = (ListView)findViewById(R.id.listView_contact_list);
	    
	    ArrayList<IContact> contactsList = null;
	    if (m_Profile != null)
	    {
	    	contactsList = m_Profile.GetContactsAsArrayList(this);
	    }
	    if (contactsList != null)
	    {
	        contactListView.setAdapter(new ContactArrayAdapter(this));
	        contactListView.setOnItemClickListener(contactListItemClickListener);
	    }
	    
	    contactButton.setOnClickListener(new OnClickContactsListener(this));
	    buttonScedule.setOnClickListener(new OnClickScheduleListener(this, m_Profile));

	}
    
	private void ShowSelectContactsDialog() {
    	// Showing a dialog to select contacts
		SelectContactsDialogFragment contactsDialog = SelectContactsDialogFragment.NewInstance(true, true);
		contactsDialog.show(getSupportFragmentManager(), "Contacts");
    }
	
    private OnItemClickListener contactListItemClickListener = new OnItemClickListener() {
     	private static final String TAG = "OnItemClickListener";

        @Override
        public void onItemClick(AdapterView<?> parent, final View view, int position, long id)
        {
    	    Log.v(TAG, "Clicked on contact (Avivit)");

    	    
        	final IContact item = ((IContact)parent.getItemAtPosition(position));
          
        	// ToDo: Update selected
        	
        	final ListView contactListView = (ListView)findViewById(R.id.listView_contact_list);
    	    if (contactListView == null)
    	    {
    	    	Log.v("ERROR!", "listView_contact_list wasn't found!");
    	    }
            ArrayAdapter<IContact> arrayAdapter = (ArrayAdapter<IContact>)contactListView.getAdapter();
    		arrayAdapter.notifyDataSetChanged();
    		
        }
    };
    
    
    @Override
    protected void onResume()
    {
    	refreshContactsList();
    	super.onResume();
    }
    
    
    private void refreshContactsList()
    {
    	// set profile list adapter and items on-click listener
    	final ListView contactsListView = (ListView)findViewById(R.id.listView_contact_list);
	    if (contactsListView == null)
	    {
	    	Log.v("ERROR!", "listView_contact_list wasn't found!");
	    }
	    
	    ArrayList<IContact> contactsList = null;
	    if (m_Profile != null)
	    {
	    	contactsList = m_Profile.GetContactsAsArrayList(this);
	    }
	    if (contactsList != null)
	    {
	    	contactsListView.setAdapter(new ContactArrayAdapter(this));
	    	contactsListView.setOnItemClickListener(contactListItemClickListener);
	    }
    }
    
	
	private TextWatcher editTextProfileNameChangedListener = new TextWatcher() {
        public void afterTextChanged(Editable s) {
        	// TBD - check for valid profile name
        }
        public void beforeTextChanged(CharSequence s, int start, int count, int after){}
        public void onTextChanged(CharSequence s, int start, int before, int count){}
    }; 
    
    
	private OnClickSaveListener buttonSaveOnClickListener = new OnClickSaveListener(this);
	
	private class OnClickSaveListener implements OnClickListener {

		private Context m_Context = null;
		public OnClickSaveListener(Context context)
		{
			m_Context = context;
		}
		
		@Override
        public void onClick(View v)
        {
			Log.v("CreateNewProfileActivity", "Trying to save Ofer");
			final EditText editTextProfileName = (EditText)findViewById(R.id.editText_profile_name);
		    if (editTextProfileName == null)
		    {
		    	Log.v("ERROR!", "listView_contact_list wasn't found!");
		    }
        	final String profileName = editTextProfileName.getText().toString();
        	
        	// if this is a new profile, create it in the DB
			if (m_IsNew)
			{
				m_Profile = AcManager.GetInstance().CreateNewProfile(m_Context, profileName);
			}
			else
			{			
				// update profile object's name
				m_Profile.SetName(profileName);
			}
        	
			for (Entry<IContact, Boolean> selectContactEntry : m_Contacts.entrySet()) {
				if (selectContactEntry.getValue()) {
					m_Profile.AddContact(CreateNewProfileActivity.this, selectContactEntry.getKey());
				}
				else {
					m_Profile.RemoveContact(CreateNewProfileActivity.this, selectContactEntry.getKey());
				}
			}
        	
			// update the profile
			AcManager.GetInstance().ModifyProfile(m_Context, m_Profile);
			
			// exit the activity
			finish();
		}
	};

	private class OnClickScheduleListener implements OnClickListener {

		private Context m_Context = null;
		private IProfile m_Profile = null;
		public OnClickScheduleListener(Context context, IProfile i_Profile)
		{
			m_Context = context;
			m_Profile = i_Profile;
		}
		
		@Override
        public void onClick(View v)
        {
			Log.v(TAG, "Opening Schedule Activity");
			
			
			 //Open Schedule Activity window
			Intent scheduleActivity = new Intent(m_Context, ScheduleActivityForProfile.class);
			scheduleActivity.putExtra(Messages.PROFILE_DETAILS_PROFILE_ID, m_Profile.GetId());
			startActivity(scheduleActivity);
			//finish();
		}
	};
	
	private class OnClickDeleteListener implements OnClickListener {

		private Context m_Context = null;
		public OnClickDeleteListener(Context context)
		{
			m_Context = context;
		}
		
		@Override
        public void onClick(View v)
        {
			Log.v(TAG, "Trying to delete Ofer");
			
			if (m_Profile != null)
			{
				// delete the profile
				AcManager.GetInstance().DeleteProfile(m_Context, m_Profile);
			}
			
			// exit the activity
			finish();
		}
	};
	
	private class OnClickContactsListener implements OnClickListener {

		private Context m_Context = null;
		public OnClickContactsListener(Context context)
		{
			m_Context = context;
		}
		
		@Override
		public void onClick(View v) {
			CreateNewProfileActivity.this.ShowSelectContactsDialog();
		}
	};
	
	@Override
	public Set<IContact> GetCurrentlySelectedContacts() {
		if (m_Profile != null) {
			return m_Profile.GetContacts(this);
		}
		
		// If profile does not exist yet, no contacts are selected. Returning empty set
		return new HashSet<IContact>();
	}
	
	@Override
	public void OnSelected(Set<IContact> selectedContacts) {
		// "Removing" all current contacts by setting their value to false
		// We need to save the removed contacts so we can remove them from the profile.
		for (Entry<IContact, Boolean> contactEntry : m_Contacts.entrySet()) {
			contactEntry.setValue(false);
		}
		
		for (IContact contact : selectedContacts) {
			if (m_Contacts.containsKey(contact)) {
				m_Contacts.remove(contact);
			}
			m_Contacts.put(contact, true);
		}
	}

	@Override
	public void OnCanceled() { }
	
    private class ContactArrayAdapter extends ArrayAdapter<IContact>
    {
    	private Context m_Context = null;
    	HashMap<IContact, Integer> m_IdMap = null;
    	
    	public ContactArrayAdapter(Context context)
    	{
    		
    		super(context, R.layout.main_menu_item_details_view, AcManager.GetInstance().GetProfileDetails(context, m_Profile.GetId()).GetContactsAsArrayList(context));
    		m_Context = context;
    		
    		updateContactsData();
    		
    	}
    	
    	public View getView(int position, View convertView, ViewGroup parent) {
    		ViewHolder holder;
    		if (convertView == null) {
    			convertView = LayoutInflater.from(m_Context).inflate(R.layout.contact_list_item, null);
    			holder = new ViewHolder();
    			holder.txt_itemName = (TextView)convertView.findViewById(R.id.contact_list_item_text);
    		    if (holder.txt_itemName == null)
    		    {
    		    	Log.v("ERROR!", "contact_list_item_text wasn't found!");
    		    }
    			holder.itemImage = (ImageView)convertView.findViewById(R.id.contact_list_item_image);
    		    if (holder.itemImage == null)
    		    {
    		    	Log.v("ERROR!", "contact_list_item_image wasn't found!");
    		    }
    			convertView.setTag(holder);
    		} else {
    			holder = (ViewHolder) convertView.getTag();
    		}
    		
    		try {
				holder.txt_itemName.setText(getItem(position).GetName(m_Context));
			} catch (PhoneContactDoesNotExistException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		holder.itemImage.setImageResource(R.drawable.contact);

    		return convertView;
    	}
    	
    	private void updateContactsData()
    	{
    		ArrayList<IContact> contactsList = AcManager.GetInstance().GetProfileDetails(m_Context, m_Profile.GetId()).GetContactsAsArrayList(m_Context);
    		m_IdMap = new HashMap<IContact, Integer>();
    		// set profiles in id-map
    		int i = 0;
    		for (IContact contact : contactsList)
    		{
    			m_IdMap.put(contact, i++);
    		}
    	}
    	
    	
    	@Override
    	public long getItemId(int position)
    	{
    		IContact item = getItem(position);
    		return m_IdMap.get(item);
    	}
    	
    	@Override
    	public boolean hasStableIds()
    	{
    		return true;
    	}
    	
    	@Override
    	public void notifyDataSetChanged()
    	{
    		updateContactsData();
    		super.notifyDataSetChanged();
    	}
    	
    	
    }
	
    static class ViewHolder
    {
		TextView txt_itemName;
		ImageView itemImage;
	}
    
}
